package controllers

import (
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"

	"github.com/golang/glog"
	"github.com/gorilla/mux"

	"eccgateway/pkg/util"
)

const (
	EdgeXUriPrefix       = "/edgex"
	TrueAddressHeaderKey = "X-Proxy-Backend"

	HttpPrefix = "http://"
)

const (
	HttpProtocol           = "http"
	OriginHostReqHeader    = "X-Origin-Host"
	ForwardedHostReqHeader = "X-Forwarded-Host"
)

type EdgeXController struct {
}

func (c *EdgeXController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	trueUri := "/" + mux.Vars(r)["rest"]

	address := r.Header.Get(TrueAddressHeaderKey)
	address = strings.Trim(address, "/")
	if !validAddress(address) {
		glog.Errorf("illegae proxy backend address format, address: %v", address)
		util.ReturnErrorResponseInResponseWriter(w, http.StatusBadRequest, fmt.Sprintf("illegae proxy backend address format, it should like http://10.0.105.72:4000"))
		return
	}

	origin, err := url.Parse(address)
	if err != nil {
		glog.Errorf("parse proxy backend address failed, address: %v, err: %v", address, err)
		util.ReturnErrorResponseInResponseWriter(w, http.StatusBadRequest, fmt.Sprintf("parse proxy backend address failed, %v", err))
		return
	}

	glog.Infof("this request will send to address: %v, uri: %v, method: %v", address, trueUri, r.Method)
	director := func(req *http.Request) {
		req.Header.Add(ForwardedHostReqHeader, req.Host)
		req.Header.Add(OriginHostReqHeader, origin.Host)
		req.URL.Scheme = HttpProtocol
		req.URL.Host = origin.Host
		req.URL.Path = trueUri
	}
	proxy := &httputil.ReverseProxy{Director: director}
	proxy.ServeHTTP(w, r)
}

func validAddress(address string) bool {
	return strings.HasPrefix(address, HttpPrefix)
}
